package io.fathom.cloud.lifecycle;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.google.inject.Binding;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Scope;
import com.google.inject.Scopes;
import com.google.inject.spi.BindingScopingVisitor;
@Singleton
public class Lifecycle {
private static final Logger log = LoggerFactory.getLogger(Lifecycle.class);
@Inject
Injector injector;
List<LifecycleListener> listeners;
synchronized List<LifecycleListener> getListeners() {
if (listeners == null) {
List<LifecycleListener> listeners = Lists.newArrayList();
for (Map.Entry<Key<?>, Binding<?>> entry : injector.getAllBindings().entrySet()) {
// final Binding<?> binding = entry.getValue();
// Object instance = entry.getValue().getProvider().get();
BindingScopingVisitor<Boolean> visitor = new IsSingletonBindingScopingVisitor();
Map<Key<?>, Binding<?>> bindings = injector.getAllBindings();
for (Binding<?> binding : bindings.values()) {
Key<?> key = binding.getKey();
// log.debug("Checking binding " + key);
Boolean foundSingleton = binding.acceptScopingVisitor(visitor);
if (foundSingleton) {
Object instance = injector.getInstance(key);
// log.debug("\tsingleton: " + instance);
if (instance instanceof LifecycleListener) {
if (listeners.contains(instance)) {
continue;
}
log.debug("Found binding " + key);
log.debug("Found lifecycle listener: {}", instance.getClass());
listeners.add((LifecycleListener) instance);
}
}
}
// binding.acceptScopingVisitor(new
// DefaultBindingScopingVisitor<Void>() {
// @Override
// public Void visitEagerSingleton() {
// Object instance = binding.getProvider().get();
// foundSingleton(instance);
// return null;
// }
//
// @Override
// public Void visitScopeAnnotation(Class<? extends Annotation>
// scopeAnnotation) {
// return super.visitScopeAnnotation(scopeAnnotation);
// }
//
// @Override
// protected Void visitOther() {
// return super.visitOther();
// }
//
// @Override
// public Void visitScope(Scope scope) {
// return super.visitScope(scope);
// }
//
// @Override
// public Void visitNoScoping() {
// return super.visitNoScoping();
// }
// });
}
this.listeners = listeners;
}
return listeners;
}
static class IsSingletonBindingScopingVisitor implements BindingScopingVisitor<Boolean> {
@Override
public Boolean visitEagerSingleton() {
// log.debug("\tfound eager singleton");
return Boolean.TRUE;
}
@Override
public Boolean visitScope(Scope scope) {
// log.debug("\t scope: " + scope);
return scope == Scopes.SINGLETON;
}
@Override
public Boolean visitScopeAnnotation(Class<? extends Annotation> scopeAnnotation) {
// log.debug("\t scope annotation: " + scopeAnnotation);
return scopeAnnotation == Singleton.class;
}
@Override
public Boolean visitNoScoping() {
return Boolean.FALSE;
}
}
public void start() throws Exception {
for (LifecycleListener listener : getListeners()) {
listener.start();
}
}
}